package top.dimples.controller.api;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.xkcoding.http.config.HttpConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthGithubRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.dimples.common.ApiResponse;
import top.dimples.common.BaseException;
import top.dimples.common.Consts;
import top.dimples.config.LuckConfigProperties;
import top.dimples.dto.GiteeDTO;
import top.dimples.dto.GithubDTO;
import top.dimples.model.UserProfile;
import top.dimples.model.UserRole;
import top.dimples.service.UserProfileService;
import top.dimples.service.UserRoleService;
import top.dimples.utils.ObjectMapperUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.HashMap;

@Api(tags = "第三方登录模块")
@Slf4j
@RestController
@RequestMapping("/api/oauth")
public class RestAuthController {

    @Autowired
    private UserProfileService userProfileService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private LuckConfigProperties luckConfigProperties;

    @ApiOperation(value = "请求第三方登录")
    @GetMapping("/login/{type}")
    public void renderAuth(HttpServletResponse response, @PathVariable("type") String type) throws IOException {
        AuthRequest authRequest = getAuthRequest(type);
        response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    }

    @ApiOperation(value = "第三方登录回调")
    @GetMapping("/callback/{type}")
    public void login(AuthCallback callback, @PathVariable("type") String type, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = getAuthRequest(type);
        AuthResponse authResponse = authRequest.login(callback);
        if (authResponse.ok()) {
            UserProfile profile = null;
            UserProfile userProfile;
            HashMap map = Convert.convert(HashMap.class, authResponse.getData());

            log.info("授权成功，用户id为{}", map.get("uuid"));

            // 码云授权登录
            if ("gitee".equalsIgnoreCase(type)) {
                GiteeDTO giteeDTO = ObjectMapperUtil.toObject(ObjectMapperUtil.toJSON(map.get("rawUserInfo")), GiteeDTO.class);

                userProfile = userProfileService.getById(giteeDTO.getId());

                // 判断是否已经注册
                if (ObjectUtil.isNotEmpty(userProfile)) {
                    ApiResponse apiResponse = userProfileService.login(userProfile);
                    HashMap tokenMap = Convert.convert(HashMap.class, apiResponse.getData());
                    response.sendRedirect(StrUtil.format("{}?token={}", luckConfigProperties.getAuthLocation(), tokenMap.get("token")));
                    return;
                }

                // 注册用户
                profile = UserProfile.builder()
                        .id(giteeDTO.getId())
                        .nickName(giteeDTO.getNickName())
                        .username(giteeDTO.getUserName())
                        .password(SecureUtil.md5(Consts.PASSWORD))
                        .email(giteeDTO.getEmail())
                        .avatarUrl(giteeDTO.getAvatarUrl())
                        .build();
                userProfileService.save(profile);
            }
            // github 授权登录
            if ("github".equalsIgnoreCase(type)) {
                GithubDTO githubDTO = ObjectMapperUtil.toObject(ObjectMapperUtil.toJSON(map), GithubDTO.class);
                userProfile = userProfileService.getById(githubDTO.getId());
                // 判断是否已经注册
                if (ObjectUtil.isNotEmpty(userProfile)) {
                    ApiResponse apiResponse = userProfileService.login(userProfile);
                    HashMap tokenMap = Convert.convert(HashMap.class, apiResponse.getData());
                    response.sendRedirect(StrUtil.format("{}?token={}", luckConfigProperties.getAuthLocation(), tokenMap.get("token")));
                    return;
                }
                // 注册用户
                profile = UserProfile.builder()
                        .id(githubDTO.getId())
                        .nickName(githubDTO.getNickName())
                        .username(githubDTO.getUserName())
                        .password(SecureUtil.md5(Consts.PASSWORD))
                        .email(githubDTO.getEmail())
                        .avatarUrl(githubDTO.getAvatarUrl())
                        .build();
                userProfileService.save(profile);
            }


            // 添加普通用户的角色
            if (ObjectUtil.isNotEmpty(profile)) {
                userRoleService.save(
                        UserRole.builder()
                                .userId(profile.getId())
                                .roleId("1468224439932977153")
                                .build()
                );
            }
            ApiResponse apiResponse = userProfileService.login(profile);
            HashMap tokenMap = Convert.convert(HashMap.class, apiResponse.getData());
            response.sendRedirect(StrUtil.format("{}?token={}", luckConfigProperties.getAuthLocation(), tokenMap.get("token")));
            return;
        }
        response.sendRedirect(luckConfigProperties.getFailLocation());
    }

    private AuthRequest getAuthRequest(String type) {

        AuthRequest authRequest = null;
        switch (type.toLowerCase()) {
            case "github":
                authRequest = new AuthGithubRequest(AuthConfig.builder()
                        .httpConfig(HttpConfig.builder()
                                .timeout(15000)
                                .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890)))
                                .build())
                        .clientId("2ac0c88da353f4d2ee65")
                        .clientSecret("72637fab8cabddfb834d8e0801978076ad02a58e")
                        .redirectUri("http://localhost:8080/oauth/callback/github")
                        .build());
                break;
            case "gitee":
                authRequest = new AuthGiteeRequest(AuthConfig.builder()
                        .clientId("334ca299c78e9cfc3ed6b1c8772bce550397a7b8f870e3803a98f8e5883a8685")
                        .clientSecret("eec8c151ae20b1f6bf4b5d84c0bf04f2125d60638d8bc810ad4cc6041edbc6ab")
                        .redirectUri("http://localhost:8080/oauth/callback/gitee")
                        .build());
                break;
            default:
                break;
        }

        if (ObjectUtil.isEmpty(authRequest)) {
            throw new BaseException(400, "没有提供该登陆方式");
        }
        return authRequest;
    }
}